package com.xayy.health.mgt.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.kawins.base.result.ResultBody;
import cn.kawins.mybatis.base.BaseController;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.github.pagehelper.PageInfo;
import com.xayy.health.core.enums.WebsocketTopicEnum;
import com.xayy.health.mgt.model.DataQuality;
import com.xayy.health.mgt.model.DataQualityReport;
import com.xayy.health.mgt.model.TaskInfo;
import com.xayy.health.mgt.model.dto.DataFeatureDto;
import com.xayy.health.mgt.model.dto.DataQualityDto;
import com.xayy.health.mgt.model.dto.TelemetryDto;
import com.xayy.health.mgt.model.vo.*;
import com.xayy.health.mgt.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zhangxa
 */
@RestController
@RequestMapping(value = "/data1")
@Api(tags = "数据处理")
public class DataController extends BaseController<DataQuality> {

    @Autowired
    private DataQualityService dataQualityService;
    @Autowired
    private DataFeatureService telemetryDataService;
    @Autowired
    private TaskInfoService taskInfoService;
    @Autowired
    private SatelliteService satelliteService;
    @Autowired
    private DataFeatureService dataFeatureService;
    @Autowired
    private TaskParamInfoService taskParamInfoService;
    @Autowired
    private TaskChildInfoService taskChildInfoService;

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;


    /**
     * 分页
     *
     * @param dataQualityDto 质量分析实体
     * @return ResultBody
     */
    @ApiOperation("分页")
    @PostMapping("page")
    public ResultBody page(@RequestBody DataQualityDto dataQualityDto) {
        PageInfo<QualityVo> pageList = dataQualityService.pageList(dataQualityDto);
        return ResultBody.success(pageList);
    }

    /**
     * 获取质量分析报告
     * @param reportVo 质量分析报告入参
     * @return ResultBody
     */
    @ApiOperation("获取质量分析报告")
    @PostMapping("getReportInfo")
    public ResultBody getReportInfo(@RequestBody ReportVo reportVo) {
        if (StrUtil.isNotEmpty(reportVo.getSatelliteCode())) {
            DataQualityReport dataQualityReport = dataQualityService.getReportInfos(reportVo);
            return ResultBody.success(dataQualityReport);
        }
        return null;

    }

    /**
     * 根据卫星代号获取质量分析数据
     * @param reportVo 分析入参
     * @return ResultBody
     */
    @ApiOperation("根据卫星代号获取质量分析数据")
    @PostMapping("/getQualityBySatelliteCode")
    public ResultBody getQualityBySatelliteCode(@RequestBody ReportVo reportVo) {
        PageInfo<QualityVo> pageList = dataQualityService.getQualityBySatelliteCode(reportVo);
        return ResultBody.success(pageList);
    }


    /**
     * excel下载
     * @param response 响应
     * @param dataQualityDto  质量分析入参
     * @throws IOException 异常
     */
    @PostMapping("download")
    @ApiOperation(value = "excel下载")
    public void download(HttpServletResponse response, @RequestBody DataQualityDto dataQualityDto) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("质量分析报告", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<DataQuality> dataQualityList = dataQualityService.selectList(dataQualityDto);
        EasyExcel.write(response.getOutputStream(), DataQuality.class)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).inMemory(true).sheet("质量分析报告")
                .doWrite(dataQualityList);
    }


    /**
     * 特征分析图表
     * @param dataFeatureDto 质量分析入参
     * @return ResultBody
     */
    @ApiOperation(value = "特征分析图表")
    @PostMapping("getFeatureEcharts")
    public ResultBody getFeatureEcharts(@RequestBody DataFeatureDto dataFeatureDto) {
        return dataQualityService.getFeatureEcharts(dataFeatureDto).body();
    }


    /**
     * 手动试算
     * @param telemetryDto 遥测入参
     * @param request 请求
     * @return ResultBody
     */
    @ApiOperation(value = "手动试算")
    @PostMapping("trial")
    public ResultBody trial(@Validated @ApiParam("入参") @RequestBody TelemetryDto telemetryDto, HttpServletRequest request) {
        telemetryDto.setEndTime(DateUtil.offsetMinute(telemetryDto.getStartTime(), (int) (Double.parseDouble(telemetryDto.getCycle()) * 60)));
        String[] paramCodes = telemetryDto.getParamCodes();
        //手动试算修改为异步调用- websocket推送结果
        asyncTrial(telemetryDto, paramCodes, request);
        return ResultBody.success();
    }

    /**
     * 异步调用试算
     *
     * @param telemetryDto 入参
     * @param paramCodes   参数代号
     */
    private void asyncTrial(TelemetryDto telemetryDto, String[] paramCodes, HttpServletRequest request) {
        ThreadUtil.execute(() -> {
            String userid = request.getHeader("Userid");
            Map<String, Object> maps = new HashMap<>(5);
            boolean flag = true;
            for (String paramCode : paramCodes) {
                telemetryDto.setParamCode(paramCode);
                try {
                    Map<String, Object> map = telemetryDataService.trial(telemetryDto, request);
                    maps.put(paramCode, map);
                } catch (Exception e) {
                    flag = false;
                    simpMessagingTemplate.convertAndSend(WebsocketTopicEnum.TRIAL.getCode() + "/" + userid, ResultBody.failed(118, e.getMessage()));
                }
            }
            if (flag) {
                System.out.println("数据处理手动试算完成");
                simpMessagingTemplate.convertAndSend(WebsocketTopicEnum.TRIAL.getCode() + "/" + userid, ResultBody.success(maps));
            }

        });
    }


    /**
     * 上线运行
     * @param telemetryDto 遥测入参
     * @return ResultBody
     */
    @ApiOperation(value = "上线运行")
    @PostMapping("online")
    public ResultBody online(@Validated @ApiParam("入参") @RequestBody TelemetryDto telemetryDto) {
        return ResultBody.success(dataFeatureService.updateSamplingInterval(telemetryDto));
    }


    /**
     * 手动剔野
     *
     * @param handWinkingVo 剔野点入参
     * @return ResultBody
     */
    @ApiOperation(value = "手动剔野")
    @PostMapping("/hand/winking")
    public ResultBody handWinking(@RequestBody HandWinkingVo handWinkingVo) {

        return dataQualityService.handWinking(handWinkingVo).body();
    }


    /**
     * 任务列表分页
     * @param subtaskPageParam 入参
     * @return ResultBody
     */
    @ApiOperation(value = "任务列表分页")
    @PostMapping("/subTaskDetail")
    @ResponseBody
    public ResultBody
    subTaskDetail(@ApiParam(value = "入参", required = true) @RequestBody SubtaskPageParam subtaskPageParam) {
        return ResultBody.success(satelliteService.subTaskDetail(subtaskPageParam));
    }


    /**
     * 交集时间覆盖
     * @param telemetryDto 入参
     * @return ResultBody
     */
    @ApiOperation(value = "交集时间覆盖")
    @PostMapping("stopChildThread")
    public ResultBody stopChildThread(@RequestBody TelemetryDto telemetryDto) {
        taskInfoService.updateStatusByTaskInfo(telemetryDto);
        return ResultBody.success("更新成功");
    }

    /**
     * 上线运行校验参数是否已在别的任务里面
     * @param telemetryDto 入参
     * @return ResultBody
     */
    @ApiOperation(value = "上线运行校验参数是否已在别的任务里面")
    @PostMapping("/online/check")
    public ResultBody checkTask(@Validated @ApiParam("入参") @RequestBody TelemetryDto telemetryDto) {
        return taskParamInfoService.checkTask(telemetryDto).body();
    }

    /**
     * 批量（单个）删除任务及其子任务
     * @param taskVo 任务入参
     * @return ResultBody
     */
    @ApiOperation(value = "批量（单个）删除任务及其子任务")
    @PostMapping("/deleteChildTask")
    public ResultBody deleteChildTask(@RequestBody TaskVo taskVo) {
        return taskChildInfoService.deleteChildTask(taskVo).body();
    }

    /**
     * 子任务参数处理展示
     * @param taskInfo 任务信息入参
     * @return ResultBody
     */
    @ApiOperation(value = "子任务参数处理展示")
    @PostMapping("/getAlgorithmTypeByChild")
    public ResultBody getAlgorithmTypeByChild(@RequestBody TaskInfo taskInfo) {
        return taskChildInfoService.getAlgorithmTypeByChild(taskInfo).body();
    }

}
